<?php

namespace app\socket\object;

use think\helper\Arr;

/**
 * 雷
 */
class Mine
{

    public $config = [
        "1" => [9, 9, 10],
        "2" => [9, 12, 20],
        "3" => [9, 16, 30],
        "4" => [16, 16, 50],
        "5" => [16, 30, 99],
    ];

    private $type = 1;

    private $map = [];

    /**
     * 创建雷区
     *
     * @param int $type 类型
     * @return $this
     */
    public function createMap($type = 1)
    {
        $this->type = $type;
        $item = Arr::get($this->config, $type, [9, 9, 10]);

        $mine = array_fill(0, $item[2], 1);
        $safe = array_fill(0, $item[0] * $item[1] - $item[2], 0);

        $all = array_merge($mine, $safe);
        $this->map = Arr::shuffle($all);
        return $this;
    }

    /**
     * 
     *
     * @param array $map
     * @param int $type
     * @return Mine
     */
    public static function create($map, $type)
    {
        $m = new Mine();
        $m->map = $map;
        $m->type = $type;
        return $m;
    }

    /**
     * 获取雷区原始地图
     *
     * @return array
     */
    public function getMap()
    {
        if (!count($this->map)) {
            $this->createMap($this->type);
        }
        return $this->map;
    }

    public function getMineType()
    {
        return $this->type;
    }

    /**
     * index转v2向量
     *
     * @param number $index
     * @return Vec2
     */
    public function getV2($index)
    {
        $item = $this->config[$this->type];
        $x = $index % $item[0];
        $y = floor($index / $item[0]);
        return new Vec2($x, $y, $item[0], $item[1]);
    }

    public function aStart($index)
    {
        $open = [];
        $close = [];
        $check = [];

        //获取当前图块信息 
        $current = $this->getTiledInfo($index);

        do {
            if (!array_key_exists((int) $index, $close)  && !in_array((int) $index, $open)) {
                $info = $this->getTiledInfo($index);
                $v2 = $this->getV2($index);
                if ($info === 0) {
                    $open[] = $index;
                    array_push($check, $this->getIndex($v2->up()), $this->getIndex($v2->down()), $this->getIndex($v2->left()), $this->getIndex($v2->right()));
                    $check = array_filter($check, function ($item) {
                        return is_numeric($item);
                    });
                } else {
                    //$close[] = $index;
                    $close[$index] = $info;
                }
            };
        } while (($index = array_pop($check)) !== null);

        return [
            "current" => $current,
            "open" => $open,
            "close" => $close
        ];
    }



    /**
     * 当前格子的信息
     *
     * @param int $index
     * @return int  -1:当前格子是雷 0:当前格子周边0雷  n:当前格子周边n雷
     */
    private function getTiledInfo($index)
    {

        $value = $this->map[$index];
        if ($value) {
            return -1;
        }
        //检测格子周围
        $v2 = $this->getV2($index);
        //检测上方
        $sum = 0;
        if ($this->getIndex($v2->up()) !== false) {
            $sum += $this->map[$this->getIndex($v2->up())];
        }

        if ($this->getIndex($v2->down()) !== false) {
            $sum += $this->map[$this->getIndex($v2->down())];
        }
        if ($this->getIndex($v2->left()) !== false) {
            $sum += $this->map[$this->getIndex($v2->left())];
        }
        if ($this->getIndex($v2->right()) !== false) {
            $sum += $this->map[$this->getIndex($v2->right())];
        }
        if ($this->getIndex($v2->leftUp()) !== false) {
            $sum += $this->map[$this->getIndex($v2->leftUp())];
        }
        if ($this->getIndex($v2->rightUp()) !== false) {
            $sum += $this->map[$this->getIndex($v2->rightUp())];
        }
        if ($this->getIndex($v2->leftDown()) !== false) {
            $sum += $this->map[$this->getIndex($v2->leftDown())];
        }
        if ($this->getIndex($v2->rightDown()) !== false) {
            $sum += $this->map[$this->getIndex($v2->rightDown())];
        }
        return (int) $sum;
    }

    /**
     * v2向量转index
     *
     * @param Vec2 $v2
     * @return int
     */
    public function getIndex($v2)
    {
        if ($v2 === false) return false;
        $item = $this->config[$this->type];
        return $v2->y * $item[0] + $v2->x;
    }

    /**
     * 获取二维向量地图
     *
     * @return array
     */
    public function getV2Map()
    {
        return array_chunk($this->map, $this->config[$this->type][0]);
    }
}
